package com.flyduck.annotation.aspect;

import com.flyduck.annotation.annotation.HeaderValidAspect;
import com.flyduck.annotation.util.CommonUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 自定义Header的AOP
 *
 * @author flyduck 2020/11/1 15:21
 * @version V1.0
 * @modify by user: flyduck 2020/11/1
 * @modify by reason:{原因}
 **/
@Aspect
@Component
public class HeaderAspect {

    /**
     * 将自定义注解作为切入点
     * 
     * @author flyduck
     * @date 2020/11/1 15:26
     * @param []
     * @return void
    */
    @Pointcut("@annotation(com.flyduck.annotation.annotation.HeaderValidAspect)")
    public void annotation() {

    }

    /**
     * 切入点执行前
     * 
     * @author flyduck
     * @date 2020/11/1 15:26
     * @param [joinPoint]
     * @return void
    */
    @Before("annotation()")
    public void before(JoinPoint joinPoint) {

    }

    /**
     * 环绕切入点
     * 
     * @author flyduck
     * @date 2020/11/1 15:26
     * @param [pjp]
     * @return java.lang.Object
    */
    @Around("annotation()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        // 从请求中获取Header和参数
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        HeaderValidAspect headerValidAspect = ((MethodSignature)pjp.getSignature()).getMethod().getAnnotation(HeaderValidAspect.class);

        // 判断自定义注解验证逻辑
        String allowRole = headerValidAspect.value();
        String requestRole = request.getHeader(CommonUtils.HEADER_CLIENT);
        if (!allowRole.equals(requestRole)) {
            return null;
        }


        // 获取注解方法的参数
        //Signature signature = pjp.getSignature();
        //MethodSignature methodSignature = (MethodSignature) signature;
        // 参数名数组
        //String[] parameterNames = ((MethodSignature) signature).getParameterNames();

        return pjp.proceed();
    }

    /**
     * 切入点执行后 包含异常
     * 
     * @author flyduck
     * @date 2020/11/1 15:27
     * @param [joinPoint]
     * @return void
    */
    @After("annotation()")
    public void after(JoinPoint joinPoint) {

    }

    /**
     * 切入点执行后 正常逻辑
     * 
     * @author flyduck
     * @date 2020/11/1 15:27
     * @param [joinPoint]
     * @return void
    */
    @AfterReturning("annotation()")
    public void afterReturning(JoinPoint joinPoint) {

    }

    /**
     * 切入点执行后 异常逻辑
     * 
     * @author flyduck
     * @date 2020/11/1 15:27
     * @param [joinPoint]
     * @return void
    */
    @AfterThrowing("annotation()")
    public void afterThrowing(JoinPoint joinPoint) {

    }
}
